package com.aos.erp.manager.service.sys.impl;

import com.aos.erp.common.bean.ResultBean;
import com.aos.erp.common.dao.mapper.Condition;
import com.aos.erp.common.exception.BizException;
import com.aos.erp.common.lock.AxLock;
import com.aos.erp.common.lock.AxLockParam;
import com.aos.erp.manager.enums.IsDel;
import com.aos.erp.manager.enums.sys.DepartmentType;
import com.aos.erp.manager.enums.sys.OrganizationState;
import com.aos.erp.manager.mapper.sys.DepartmentMapper;
import com.aos.erp.manager.model.sys.Department;
import com.aos.erp.manager.model.sys.User;
import com.aos.erp.manager.model.sys.vo.MenuTree;
import com.aos.erp.manager.model.sys.vo.MenuVo;
import com.aos.erp.manager.remote.model.Organization;
import com.aos.erp.manager.remote.sys.OrganizationService;
import com.aos.erp.manager.service.sys.DepartmentService;
import com.aos.erp.manager.util.CodeUtil;
import com.aos.erp.manager.util.TreeUtil;
import com.aos.erp.manager.util.UserUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @program: erp
 * @description: 部门组织service
 * @author: tanzhiyu
 * @create: 2018-11-01 19:23
 **/
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {
    @Resource
    private DepartmentMapper departmentMapper;
    @Resource
    OrganizationService organizationService;

    /**
     * 新增部门组织---分所
     *
     * @param divisionCode 分所组织code
     * @param name         分所名称
     * @param appCode      应用code
     * @throws Exception
     */
    @Override
    public void addBeanDivision(String divisionCode, String name, String appCode) throws Exception {
        Department department = new Department();
        department.setCreated(new Date());
        String type = DepartmentType.division.getValue().toString();
        department.setDepType(type);
        department.setDepCode(divisionCode);
        department.setParentId(0l);
        department.setName(name);
        department.setIsDel(Integer.valueOf(IsDel.normal.getValue().toString()));
        this.save(department);
        //TODO 同步机构
        synOrgInfo(divisionCode, name, null, Integer.valueOf(OrganizationState.normal.getValue().toString()), appCode);
    }

    /**
     * 新增部门组织---总校
     *
     * @param divisionCode 分所组织code
     * @param schoolCode   驾校组织code
     * @param name         驾校名称
     * @param appCode      应用code
     * @throws Exception
     */
    public Long addBeanSchool(String divisionCode, String schoolCode, String name, String appCode) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("dep_code", divisionCode);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("分所组织code错误");
        }
        Department department = new Department();
        department.setParentId(dep.getId());
        department.setParentCode(dep.getDepCode());
        department.setCreated(new Date());
        String type = DepartmentType.school.getValue().toString();
        department.setDepType(type);
        department.setIsDel(Integer.valueOf(IsDel.normal.getValue().toString()));
        department.setDepCode(schoolCode);
        department.setName(name);
        departmentMapper.insertObject(department);

        //TODO 同步机构
        synOrgInfo(schoolCode, name, dep.getDepCode(), Integer.valueOf(OrganizationState.normal.getValue().toString()), appCode);
        return department.getId();
    }

    /**
     * 新增部门组织---分校/报名点
     *
     * @param parentSchoolCode 父级驾校组织code
     * @param schoolCode       驾校组织code
     * @param name             部门名称
     * @param depType          部门类型
     * @param appCode          应用code
     * @throws Exception
     */
    public Long addBeanSchoolBranch(String parentSchoolCode, String schoolCode, String name, String depType, String appCode) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("dep_code", parentSchoolCode);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("父级驾校组织code错误");
        }
        Department department = new Department();
        department.setParentId(dep.getId());
        department.setParentCode(dep.getDepCode());
        department.setCreated(new Date());
        department.setDepType(depType);
        department.setDepCode(schoolCode);
        department.setName(name);
        department.setIsDel(Integer.valueOf(IsDel.normal.getValue().toString()));
        departmentMapper.insertObject(department);

        //TODO 同步机构
        synOrgInfo(schoolCode, name, dep.getDepCode(), Integer.valueOf(OrganizationState.normal.getValue().toString()), appCode);
        return department.getId();
    }

    /**
     * 新增部门---部门
     *
     * @param depCode 父级组织code
     * @param name    名称
     * @param appCode 应用code
     */
    public String addBeanDepartment(String depCode, String name, String appCode) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("dep_code", depCode);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("父级组织code错误");
        }

        String depType = DepartmentType.department.getValue().toString();
        Map<String, Object> params = new HashMap<>();
        params.put("parentId", dep.getId());
        params.put("depType", depType);
        Department depVo = baseMapper.findByParams(params);
        String code = depCode + depType + "00001";
        if (depVo != null) {
            String depVoCode = depVo.getDepCode();
            String newCode = depVoCode.substring(depVoCode.length() - 5, depVoCode.length());
            code = depCode + CodeUtil.getNewEquipmentNo(depType, newCode);
        }

        Department department = new Department();
        department.setParentId(dep.getId());
        department.setParentCode(dep.getDepCode());
        department.setCreated(new Date());
        department.setDepType(depType);
        department.setDepCode(code);
        department.setName(name);
        department.setIsDel(Integer.valueOf(IsDel.normal.getValue().toString()));
        this.save(department);
        //TODO 同步机构
        synOrgInfo(code, name, dep.getDepCode(), Integer.valueOf(OrganizationState.normal.getValue().toString()), appCode);
        return code;
    }

    /**
     * 同步机构
     *
     * @param code       机构code
     * @param name       机构名称
     * @param parentCode 父级机构code
     * @param state      机构状态(0 删除 1 可用 默认 2 不可用)
     * @param appCode    应用code
     * @throws Exception
     */
    public void synOrgInfo(String code, String name, String parentCode, Integer state, String appCode) throws BizException {
        Organization orgInfo = new Organization();
        orgInfo.setAppCode(appCode);
        orgInfo.setCode(code);
        orgInfo.setName(name);
        orgInfo.setParentCode(parentCode);
        orgInfo.setStatus(state);
        ResultBean o = organizationService.synOrgInfo(orgInfo);
        if (ResultBean.CODE_FAIL == o.getCode()) {
            throw new BizException(o.getErrMsg());
        }
    }

    /**
     * 根据部门ID批量删除部门
     *
     * @param depId
     * @param appCode 应用code
     * @return
     * @throws Exception
     */
    public int isDel(String depId, String appCode) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("id", depId);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("部门组织id错误");
        }
        dep.setIsDel(Integer.valueOf(IsDel.del.getValue().toString()));
        int i = baseMapper.updateObjectBatch(dep);
        //TODO 同步机构删除
        deleteOrgInfo(dep.getDepCode(), appCode);
        return i;
    }

    /**
     * 同步机构删除
     *
     * @param code    机构code
     * @param appCode 应用appCode
     * @throws Exception
     */
    public void deleteOrgInfo(String code, String appCode) throws Exception {
        ResultBean o = organizationService.deleteOrgInfo(appCode, code);
        if (ResultBean.CODE_FAIL == o.getCode()) {
            throw new BizException(o.getErrMsg());
        }
    }

    /**
     * 根据部门code批量删除部门
     *
     * @param depCode
     * @return
     * @throws Exception
     */
    public int isDelByDepCode(String depCode) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("dep_code", depCode);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("部门组织id错误");
        }
        dep.setIsDel(Integer.valueOf(IsDel.del.getValue().toString()));
        int i = baseMapper.updateObjectBatch(dep);
        return i;
    }

    /**
     * 根据部门ID修改部门
     *
     * @param depId   部门ID
     * @param name    部门名称
     * @param appCode 应用appCode
     * @return
     * @throws Exception
     */
    public int updateObject(String depId, String name, String appCode) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("id", depId);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("部门组织id错误");
        }
        dep.setName(name);
        dep.setUpdated(new Date());
        int i = baseMapper.updateObject(dep);
        //TODO 同步机构
        synOrgInfo(dep.getDepCode(), name, dep.getParentCode(), Integer.valueOf(OrganizationState.normal.getValue().toString()), appCode);
        return i;
    }

    /**
     * 根据部门组织code查询
     *
     * @param depCode
     * @return
     * @throws Exception
     */
    public Department findByDepCode(String depCode) throws Exception {
        Map<String, Object> params = new HashMap<>();
        params.put("depCode", depCode);
        Department department = baseMapper.findByParams(params);
        return department;
    }

    /**
     * "获取分所组织code
     *
     * @param code 分所代码
     * @return
     */
    public String getDepCodeDivision(String code) throws Exception {
        String type = DepartmentType.division.getValue().toString();
        return type + code;
    }

    /**
     * 获取总校组织code
     *
     * @param divisionCode 分所组织code
     * @return
     */
    @AxLock(prefix = "school:depCodeSchool")
    public String getDepCodeSchool(@AxLockParam String divisionCode) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("dep_code", divisionCode);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("分所组织code错误");
        }

        String depType = DepartmentType.school.getValue().toString();
        Map<String, Object> params = new HashMap<>();
        params.put("parentId", dep.getId());
        params.put("depType", depType);
        Department depVo = baseMapper.findByParams(params);
        String depCode = divisionCode + depType + "00001";
        if (depVo != null) {
            String code = depVo.getDepCode();
            String newCode = code.substring(code.length() - 5, code.length());
            depCode = divisionCode + CodeUtil.getNewEquipmentNo(depType, newCode);
        }
        return depCode;
    }

    /**
     * 获取分校/报名点组织code
     *
     * @param schoolCode 总校组织code、分校组织code
     * @param depType    部门类型[F:分校;B:报名点]
     * @return
     * @throws Exception
     */
    @AxLock(prefix = "school:depCodeBranch")
    public String getDepCodeBranch(@AxLockParam String schoolCode, @AxLockParam String depType) throws Exception {
        Condition condition = new Condition(User.class);
        condition.eqColumn("dep_code", schoolCode);
        Department dep = baseMapper.selectOne(condition.getWrapper());
        if (dep == null) {
            throw new BizException("驾校组织code错误");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("parentId", dep.getId());
        params.put("depType", depType);
        Department depVo = baseMapper.findByParams(params);
        String depCode = schoolCode + depType + "00001";
        if (depVo != null) {
            String code = depVo.getDepCode();
            String newCode = code.substring(code.length() - 5, code.length());
            depCode = schoolCode + CodeUtil.getNewEquipmentNo(depType, newCode);
        }
        return depCode;
    }


    /**
     * 获取组织树
     *
     * @param params
     * @return
     * @throws Exception
     */
    public List<MenuTree> selectTree(Map<String, Object> params) throws Exception {
        List<MenuVo> menus = departmentMapper.selectTree(params);
        if (menus == null || menus.size() == 0) {
            return new ArrayList<MenuTree>();
        }
        return getMenuTree(menus, menus.get(0).getParentId());
    }

    private List<MenuTree> getMenuTree(List<MenuVo> menus, Long root) {
        List<MenuTree> trees = new ArrayList<MenuTree>();
        MenuTree node = null;
        for (MenuVo menu : menus) {
            node = new MenuTree();
            BeanUtils.copyProperties(menu, node);
            trees.add(node);
        }
        return TreeUtil.bulid(trees, root);
    }

    /**
     * 根据部门类型进行信息
     *
     * @param depType
     * @return
     */
    @Override
    public List<Department> selectByParams(String depType) {
        Map<String, Object> params = new HashMap<>();
        params.put("depType", depType);
        return departmentMapper.selectByParams(params);
    }

    /**
     * 根据部门类型进行分页
     *
     * @param pageIndex
     * @param pageSize
     * @param depCode    部门组织code
     * @param depName    部门名称
     * @param depType    部门类型
     * @param parentCode 部门父级code
     * @return
     */
    @Override
    public IPage<Department> queryByPage(Integer pageIndex, Integer pageSize, String depCode, String depName, String depType, String parentCode) {
        Page<Department> pageBean = new Page<Department>(pageIndex, pageSize);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("depCode", depCode);
        map.put("depName", depName);
        map.put("depType", depType);
        map.put("parentCode", parentCode);
        map.put("isDel", IsDel.normal.getValue().toString());
        map.put("pageBean", pageBean);
        List<Department> list = departmentMapper.selectByParams(map);
        IPage<Department> page = pageBean;
        page.setRecords(list);
        return page;
    }

    /**
     * 同步根据当前用户机构code查角色信息
     *
     * @param currentUserId 当前登录用户id
     * @return
     */
    public Object queryByOrganizationCode(String currentUserId) throws Exception {
        String code = UserUtil.getUserDepCode(currentUserId);//机构code
        return queryRoleByOrganizationCode(code);
    }

    /**
     * 同步根据机构code查角色信息
     *
     * @param organizationCode 机构code
     * @return
     * @throws Exception
     */
    public Object queryRoleByOrganizationCode(String organizationCode) throws Exception {
        ResultBean o = organizationService.queryByOrganizationCode(organizationCode);
        if (ResultBean.CODE_FAIL == o.getCode()) {
            throw new BizException(o.getErrMsg());
        }
        return o.getData();
    }
}
